/**********************************************************************
 *File		:	key.c
 *Time		:	2023/6/7
 *Author		:	Bryan He（贺璧）
 *Discreption:
 *
 ************************************************************************/
#include "stm32f0xx_hal.h"
#include "stm32f0xx_hal_def.h"
#include "stm32f0xx_hal_gpio.h"
#include "stm32f0xx_hal_i2c.h"
#include "key.h"

/*#TODO: You have to config below items which depend on your hardware cfg and which MCU you used.*/
#define key_get_gpio_state(port,pin)  HAL_GPIO_ReadPin(port,pin)

static KEY_TASK_T k_task;

const ExKyeInfo ex_key_map[GPIO_KEY_MAX] = {
    {
        .kcode = HW_KEY_FRONT_LED,
        .port = GPIOB,
        .pin = GPIO_PIN_14,
    },
    {
        .kcode = HW_MUSIC_DUCKING,
        .port = GPIOB,
        .pin = GPIO_PIN_13,
    },
    {
        .kcode = HW_OUTDOOR_MODE,
        .port = GPIOB,
        .pin = GPIO_PIN_12,
    },
    {
        .kcode = HW_VOICING_MODE,
        .port = GPIOB,
        .pin = GPIO_PIN_11,
    },
    {
        .kcode = HW_FEEDBACK_ELIM,
        .port = GPIOB,
        .pin = GPIO_PIN_10,
    },
};
/**********************************************************************************/

void io_key_task_handle(void) { /*#TODO:Invoked in 1mS loop*/
    GPIO_PinState pio;
    u8 j;

    k_task.app_tick++;
    if (k_task.app_tick < KEY_POLLING_INTERVAL) return;
    k_task.app_tick = 0;

    for (j = 0; j < GPIO_KEY_MAX; j++) {
        if (k_task.pKeyTable[j].port != 0) {
            pio = key_get_gpio_state((GPIO_TypeDef*)k_task.pKeyTable[j].port, k_task.pKeyTable[j].pin);
            if (pio == GPIO_PIN_SET) { /*Up*/
                if (k_task.ex_k_cnt[j] != 0) {
                    k_task.ex_k_cnt[j]--;
                    if (k_task.ex_k_cnt[j] == 0 && k_task.k_event_cb) {
                        k_task.k_event_cb(IO_K_EVENT_VK_UP, k_task.pKeyTable[j].kcode);
                    }
                }
            } else { /*Down*/
                if (k_task.ex_k_cnt[j] < KEY_DEBOUNCE_TIME) {
                    k_task.ex_k_cnt[j]++;
                    if (k_task.ex_k_cnt[j] >= KEY_DEBOUNCE_TIME && k_task.k_event_cb) {
                        k_task.k_event_cb(IO_K_EVENT_VK_DW, k_task.pKeyTable[j].kcode);
                    }
                }
            }
        }
    }
}

void io_key_task_init(io_k_event_cb k_event_cb) {
  memset(&k_task, 0, sizeof(k_task));
  k_task.pKeyTable = ex_key_map;
  k_task.k_event_cb = k_event_cb;
}

/**************************************************************/